#ifndef LOG_HEX_H
#define LOG_HEX_H

#include "utility/Noncopyable.h"
#include "utility/type.h"

#include <algorithm>
#include <array>

class Hex final {
public:
    template<typename T> explicit Hex(T t);
    ~Hex() = default;

    const char *data() const { return _buffer.data(); }
    std::size_t length() const { return _length; }

private:
    NONCOPYABLE(Hex);

    std::array<char, 1 << 5> _buffer;
    const std::size_t _length;
};


template<typename T>
Hex::Hex(T t): _buffer{}, _length{2 + 2 * sizeof(t)} {
    STATIC_ASSERT_INTEGRAL(T);
    static constexpr auto HEX_DIGIT = "0123456789abcdef";
    static constexpr std::make_unsigned_t<T> HEX_SIZE = 0x10;
    _buffer.at(0) = '0';
    _buffer.at(1) = 'x';
    auto v = static_cast<std::make_unsigned_t<T>>(t);
    for (std::size_t i = 2; i < _length; ++i) {
        if (!v) {
            _buffer.at(i) = '0';
            continue;
        }
        _buffer.at(i) = HEX_DIGIT[v % HEX_SIZE];
        v /= HEX_SIZE;
    }
    std::reverse(_buffer.begin() + 2, _buffer.begin() + _length);
}

#endif